﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="TestExperiments.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Threading
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Testing.Threading;
    using EventPattern;

    [TestClass]
    public class TestExperiments : AsynchronousTest
    {
        [TestInitialize]
        public void Initialize()
        {
        }

        [TestMethod, AsynchronousTest]
        public void Test_Different_Usages()
        {
            EnqueueAction(() =>
                {
                    var factory = TestTaskFactories.Synchronous;

                    var result = 0;
                    Func<int> func = () => 1;
                    var task1 = factory.FromAsync<int>(func.BeginInvoke, func.EndInvoke);
                    task1.Start(null);
                    if (task1.Error == null)
                    {
                        Action<int> action = i => result = i;
                        var task2 = factory.FromAsync(action.BeginInvoke, action.EndInvoke, task1.Result);
                        task2.Start(
                            r =>
                                {
                                    EnqueueAction(() => Assert.AreEqual(1, result));
                                    EnqueueCompleted();
                                });
                    }
                });
        }

        [TestMethod, AsynchronousTest]
        public void Test_Different_Usages1()
        {
            EnqueueAction(() =>
                {
                    //var factory = TestFactories.Synchronous;
                    var task = TestTaskFactories.Synchronous.FromYield<Employee>(
                        c => GetEmployee(c, TestTaskFactories.Synchronous, 1, true));
                    task.Start(r => EnqueueCompleted());
                });
        }

        public IEnumerable<ITask> GetEmployee(YieldPatternContext<Employee> context, TaskFactory taskFactory, int id, bool includeName)
        {
            // get employees
            var getEmployee = DelegateThreadDebugger.Debug<int, Employee>(
                "GetEmployee", (id1) => new Employee(id1));
            var getEmployeeTask = taskFactory.FromAsync<int, Employee>(getEmployee.BeginInvoke, getEmployee.EndInvoke, id);
            yield return getEmployeeTask;
            context.Result = getEmployeeTask.Result;

            // get name if includeName == true
            if (context.Result != null && includeName)
            {
                var getEmployeeName = DelegateThreadDebugger.Debug<int, string>(
                    "GetEmployeeName", id1 => "Jason");
                var getNameTask = taskFactory.FromAsync<int, string>(
                    getEmployeeName.BeginInvoke, getEmployeeName.EndInvoke, id);
                yield return getNameTask;
                context.Result.Name = getNameTask.Result;
            }
        }

        #region Nested type: Test1

        public class Test1 : Task
        {
            public Test1(TaskScheduler scheduler) : base(scheduler)
            {
            }

            protected override ITaskBinding CreateBinding()
            {
                return base.CreateBinding();
            }
        }

        #endregion
    }

    public class Employee
    {
        private readonly int _id;
        public string Name;

        public Employee(int id)
        {
            _id = id;
        }

        public int Id
        {
            get { return _id; }
        }
    }
}